home *** CD-ROM | disk | FTP | other *** search
- /*
- File: Collections.cpp
-
- Contains: Sample collection functions & classes
-
- Written by: Steve Smith
-
- Copyright: © 1995 by Apple Computer, Inc., all rights reserved.
-
- Description:
- CList: Generic unordered list
- COrderedList: Generic ordered list
- CFrameList: Unordered list of frames -
- frames automatically refcounted when
- added/removed from list.
- CQueue: Generic queue collection
- CStack: Generic stack collection
- */
-
-
- #ifndef _SAMPLECOLLECTIONS_
- #include "SampleCollections.h"
- #endif
-
- // --- OpenDoc Includes ---
-
- #ifndef _ODTYPES_
- #include <ODTypes.h>
- #endif
-
- #ifndef SOM_ODFrame_xh
- #include <Frame.xh>
- #endif
-
- // --- OpenDoc Utilities ---
-
- #ifndef _EXCEPT_
- #include <Except.h>
- #endif
-
- #ifndef _ODNEW_
- #include <ODNew.h>
- #endif
-
- #ifndef _LINKLIST_
- #include <LinkList.h>
- #endif
-
- #ifndef _LIMITS_
- #include <Limits.h>
- #endif
-
- #ifndef _ODUTILS_
- #include <ODUtils.h>
- #endif
-
-
- //====================================================================
- // CGenericLink
- //====================================================================
-
- CGenericLink::CGenericLink()
- :Link()
- {
- fValue = kODNULL;
- }
-
- CGenericLink::CGenericLink(void* value)
- :Link()
- {
- fValue = value;
- }
-
- CGenericLink::~CGenericLink()
- {
- }
-
- void* CGenericLink::GetValue()
- {
- return fValue;
- }
-
- void CGenericLink::SetValue(void* value)
- {
- fValue = value;
- }
-
- //====================================================================
- // CFrameLink
- //====================================================================
-
- CFrameLink::CFrameLink()
- :CGenericLink()
- {
- }
-
- CFrameLink::CFrameLink(ODFrame* frame)
- :CGenericLink()
- {
- Environment* ev = somGetGlobalEnvironment();
- frame->Acquire(ev);
- fValue = (void*)frame;
- }
-
- CFrameLink::~CFrameLink()
- {
- if ( fValue ) {
- Environment* ev = somGetGlobalEnvironment();
- ((ODFrame*)fValue)->Release(ev);
- }
- }
-
- ODFrame* CFrameLink::GetFrame()
- {
- return ((ODFrame*)fValue);
- }
-
- void CFrameLink::SetFrame(ODFrame* frame)
- {
- Environment* ev = somGetGlobalEnvironment();
-
- if ( fValue ) ((ODFrame*)fValue)->Release(ev);
- if ( frame ) frame->Acquire(ev);
-
- fValue = (void*)frame;
- }
-
- //====================================================================
- // CList
- //====================================================================
-
- CList::CList()
- {
- }
-
- CList::~CList()
- {
- fList.DeleteAllLinks();
- }
-
- ODBoolean CList::IsEmpty() const
- {
- return fList.IsEmpty();
- }
-
- ODULong CList::Count() const
- {
- return fList.Count();
- }
-
- ODBoolean CList::Contains(const void* value)
- {
- if ( fList.IsEmpty() ) return kODFalse;
-
- LinkedListIterator iter(&fList);
- for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
- {
- if ( ((CGenericLink*)link)->GetValue() == value )
- return kODTrue;
- }
-
- return kODFalse;
- }
-
- void CList::DeleteAllLinks()
- {
- LinkedListIterator iter(&fList);
- for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
- {
- delete (((CGenericLink*)link)->GetValue());
- }
- fList.RemoveAll();
- }
-
- void CList::RemoveAllLinks()
- {
- fList.RemoveAll();
- }
-
- void CList::Delete(void* value)
- {
- LinkedListIterator iter(&fList);
- for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
- {
- if ( ((CGenericLink*)link)->GetValue() == value )
- {
- delete (((CGenericLink*)link)->GetValue());
- fList.Remove(*link);
- return;
- }
- }
- }
-
- void CList::Remove(void* value)
- {
- LinkedListIterator iter(&fList);
- for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
- {
- if ( ((CGenericLink*)link)->GetValue() == value )
- {
- fList.Remove(*link);
- return;
- }
- }
- }
-
- void CList::Add(void* value)
- {
- CGenericLink* link = new CGenericLink(value);
- fList.AddLast(link);
- }
-
-
- //====================================================================
- // CListIterator
- //====================================================================
-
- CListIterator::CListIterator(CList* list)
- {
- fIter = new LinkedListIterator(&list->fList);
- }
-
- CListIterator::~CListIterator()
- {
- delete fIter;
- }
-
- void* CListIterator::First()
- {
- CGenericLink* link = (CGenericLink*) fIter->First();
-
- //$$$$$ for empty list, link will be null
- return (void*) link ? link->GetValue() : kODNULL;
- }
-
- void* CListIterator::Next()
- {
- CGenericLink* link = (CGenericLink*) fIter->Next();
-
- //$$$$$ At end of list, link will be null
- return (void*) link ? link->GetValue() : kODNULL;
- }
-
- void* CListIterator::Previous()
- {
- CGenericLink* link = (CGenericLink*) fIter->Previous();
-
- //$$$$$ At head of list, link will be null
- return (void*) link ? link->GetValue() : kODNULL;
- }
-
- void* CListIterator::Last()
- {
- CGenericLink* link = (CGenericLink*) fIter->Last();
-
- //$$$$$ for empty list, link will be null
- return (void*) link ? link->GetValue() : kODNULL;
- }
-
- void* CListIterator::Current()
- {
- CGenericLink* link = (CGenericLink*) fIter->Current();
-
- //$$$$$ for empty list, link will be null
- return (void*) link ? link->GetValue() : kODNULL;
- }
-
- ODBoolean CListIterator::IsNotComplete()
- {
- return fIter->IsNotComplete();
- }
-
- void CListIterator::RemoveCurrent()
- {
- fIter->RemoveCurrent();
- }
-
- void CListIterator::DeleteCurrent()
- {
- CGenericLink* link = (CGenericLink*) fIter->Current();
- fIter->RemoveCurrent();
-
- //$$$$$ for empty list, link is null
- if (link)
- delete link->GetValue();
-
- delete link;
- }
-
- //====================================================================
- // COrderedList
- //====================================================================
-
- COrderedList::COrderedList()
- {
- }
-
- COrderedList::~COrderedList()
- {
- fList.DeleteAllLinks();
- }
-
- COrderedList::COrderedList(COrderedList *list)
- {
- // (MH) Copy constructor for COrderedList
- COrdListIterator iter(list);
- for (void* elem = iter.First(); iter.IsNotComplete(); elem = iter.Next())
- {
- this->AddLast(elem);
- }
- }
-
- ODBoolean COrderedList::IsEmpty() const
- {
- return fList.IsEmpty();
- }
-
- ODULong COrderedList::Count() const
- {
- return fList.Count();
- }
-
- ODBoolean COrderedList::Contains(const void* value)
- {
- if ( fList.IsEmpty() ) return kODFalse;
-
- LinkedListIterator iter(&fList);
- for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
- {
- if ( ((CGenericLink*)link)->GetValue() == value )
- return kODTrue;
- }
-
- return kODFalse;
- }
-
- ODUShort COrderedList::Position(const void* value)
- {
- if ( fList.IsEmpty() ) return kListIsEmpty;
-
- ODUShort position = 0;
- LinkedListIterator iter(&fList);
- for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
- {
- position++;
- if ( ((CGenericLink*)link)->GetValue() == value )
- return kODTrue;
- }
-
- return kItemNotFound;
- }
-
- void COrderedList::DeleteAllLinks()
- {
- LinkedListIterator iter(&fList);
- for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
- {
- delete (((CGenericLink*)link)->GetValue());
- }
- fList.RemoveAll();
- }
-
- void COrderedList::RemoveAllLinks()
- {
- fList.RemoveAll();
- }
-
- void COrderedList::Delete(void* value)
- {
- LinkedListIterator iter(&fList);
- for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
- {
- if ( ((CGenericLink*)link)->GetValue() == value )
- {
- delete (((CGenericLink*)link)->GetValue());
- fList.Remove(*link);
- return;
- }
- }
- }
-
- void COrderedList::Remove(void* value)
- {
- LinkedListIterator iter(&fList);
- for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
- {
- if ( ((CGenericLink*)link)->GetValue() == value )
- {
- fList.Remove(*link);
- return;
- }
- }
- }
-
- void* COrderedList::RemoveFirst()
- {
- CGenericLink* link = (CGenericLink*) fList.RemoveFirst();
- return link ? (void*) link->GetValue() : (void*)kODNULL;
- }
-
- void* COrderedList::RemoveLast()
- {
- CGenericLink* link = (CGenericLink*) fList.RemoveLast();
- return link ? (void*) link->GetValue() : (void*)kODNULL;
- }
-
- void COrderedList::AddBefore(const void* existing, void* value)
- {
- LinkedListIterator iter(&fList);
- for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
- {
- if ( ((CGenericLink*)link)->GetValue() == existing )
- {
- CGenericLink* newLink = new CGenericLink(value);
- fList.AddBefore(*link,newLink);
- return;
- }
- }
- }
-
- void COrderedList::AddAfter(const void* existing, void* value)
- {
- LinkedListIterator iter(&fList);
- for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
- {
- if ( ((CGenericLink*)link)->GetValue() == existing )
- {
- CGenericLink* newLink = new CGenericLink(value);
- fList.AddAfter(*link,newLink);
- return;
- }
- }
- }
-
- void COrderedList::AddFirst(void* value)
- {
- CGenericLink* link = new CGenericLink(value);
- fList.AddFirst(link);
- }
-
- void COrderedList::AddLast(void* value)
- {
- CGenericLink* link = new CGenericLink(value);
- fList.AddLast(link);
- }
-
- void* COrderedList::After(const void* value) const
- {
- LinkedListIterator iter((LinkedList*)&fList);
- for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
- {
- if ( ((CGenericLink*)link)->GetValue() == value )
- {
- Link* after = fList.After(*link);
- // $$$$$ After may be null, if matched element was at end of list!
- return (void*) after ? ((CGenericLink*)after)->GetValue() : kODNULL;
- }
- }
- return kODNULL;
- }
-
- void* COrderedList::Before(const void* value) const
- {
- LinkedListIterator iter((LinkedList*)&fList);
- for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
- {
- if ( ((CGenericLink*)link)->GetValue() == value )
- {
- //$$$$$ it would be nice to call the previous link 'before', not 'after'
- Link* before = fList.Before(*link);
- // $$$$$ before may be null, if matched element was at head of list!
- return (void*) before ? ((CGenericLink*)before)->GetValue() : kODNULL;
- }
- }
- return kODNULL;
- }
-
- void* COrderedList::First() const
- {
- CGenericLink* link = (CGenericLink*) fList.First();
-
- //$$$$$ (MH) More empty list problems fixed
- return (void*) link ? link->GetValue() : kODNULL;
- }
-
- void* COrderedList::Last() const
- {
- CGenericLink* link = (CGenericLink*) fList.Last();
-
- //$$$$$ (MH) More empty list problems fixed
- return (void*) link ? link->GetValue() : kODNULL;
- }
-
- //====================================================================
- // COrdListIterator
- //====================================================================
-
- COrdListIterator::COrdListIterator(COrderedList* list)
- {
- fIter = new LinkedListIterator(&list->fList);
- }
-
- COrdListIterator::~COrdListIterator()
- {
- }
-
-
- //====================================================================
- // CFrameList
- //====================================================================
-
- CFrameList::CFrameList()
- {
- }
-
- CFrameList::~CFrameList()
- {
- Environment* ev = somGetGlobalEnvironment();
-
- LinkedListIterator iter(&fList);
- for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
- {
- // ((CFrameLink*)link)->GetFrame()->Release(ev);
- iter.RemoveCurrent();
- delete link;
- }
- }
-
- ODBoolean CFrameList::IsEmpty() const
- {
- return fList.IsEmpty();
- }
-
- ODULong CFrameList::Count() const
- {
- return fList.Count();
- }
-
- ODBoolean CFrameList::Contains(const ODFrame* frame)
- {
- if ( fList.IsEmpty() ) return kODFalse;
-
- Environment* ev = somGetGlobalEnvironment();
-
- LinkedListIterator iter(&fList);
- for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
- {
- if ( ODObjectsAreEqual(ev, ((CFrameLink*)link)->GetFrame(), (ODFrame*)frame) )
- return kODTrue;
- }
-
- return kODFalse;
- }
-
- void CFrameList::Remove(ODFrame* frame)
- {
- Environment* ev = somGetGlobalEnvironment();
-
- Link* link = kODNULL;
- LinkedListIterator iter(&fList);
- for (link=iter.First();iter.IsNotComplete();link=iter.Next())
- {
- if ( ODObjectsAreEqual(ev, ((CFrameLink*)link)->GetFrame(), frame) )
- {
- // frame->Release(ev);
- // iter.RemoveCurrent();
- // delete link;
- break;
- }
- }
-
- if ( link )
- {
- fList.Remove(*link);
- delete link;
- }
- else
- THROW(kODErrInvalidFrame);
- }
-
- void CFrameList::Add(ODFrame* frame)
- {
- CFrameLink* link = new CFrameLink(frame);
- fList.AddLast(link);
- }
-
- ODFrame* CFrameList::GetFrame()
- {
- CFrameLink* link = (CFrameLink*) fList.First();
- return link->GetFrame();
- }
-
- //====================================================================
- // CFrameListIterator
- //====================================================================
-
- CFrameListIterator::CFrameListIterator(CFrameList* list)
- {
- fIter = new LinkedListIterator(&list->fList);
- }
-
- CFrameListIterator::~CFrameListIterator()
- {
- delete fIter;
- }
-
- ODFrame* CFrameListIterator::First()
- {
- CFrameLink* link = (CFrameLink*) fIter->First();
- return link->GetFrame();
- }
-
- ODFrame* CFrameListIterator::Next()
- {
- CFrameLink* link = (CFrameLink*) fIter->Next();
- return link->GetFrame();
- }
-
- ODFrame* CFrameListIterator::Previous()
- {
- CFrameLink* link = (CFrameLink*) fIter->Previous();
- return link->GetFrame();
- }
-
- ODFrame* CFrameListIterator::Last()
- {
- CFrameLink* link = (CFrameLink*) fIter->Last();
- return link->GetFrame();
- }
-
- ODFrame* CFrameListIterator::Current()
- {
- CFrameLink* link = (CFrameLink*) fIter->Current();
- return link->GetFrame();
- }
-
- ODBoolean CFrameListIterator::IsNotComplete()
- {
- return fIter->IsNotComplete();
- }
-
- void CFrameListIterator::ReleaseCurrent()
- {
- Environment* ev = somGetGlobalEnvironment();
-
- CFrameLink* link = (CFrameLink*) fIter->Current();
- link->GetFrame()->Release(ev);
- fIter->RemoveCurrent();
- }
-
- //====================================================================
- // CStack
- //====================================================================
-
- CStack::CStack()
- {
- fMaxDepth = USHRT_MAX;
- }
-
- CStack::~CStack()
- {
- fStack.DeleteAllLinks();
- }
-
- ODBoolean CStack::IsEmpty()
- {
- return fStack.IsEmpty();
- }
-
- void CStack::EmptyStack(ODBoolean deleteEntries)
- {
- if ( deleteEntries )
- {
- LinkedListIterator iter(&fStack);
- for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
- {
- delete (((CGenericLink*)link)->GetValue());
- fStack.Remove(*link);
- }
- }
- else
- fStack.DeleteAllLinks();
- }
-
- ODUShort CStack::SetSize(ODUShort maxDepth)
- {
- ODULong curSize = fStack.Count();
-
- if ( curSize > maxDepth )
- fMaxDepth = (ODUShort) curSize;
- else
- fMaxDepth = maxDepth;
-
- return fMaxDepth;
- }
-
- ODBoolean CStack::PushEntry(void* entry)
- {
- if ( (ODUShort)fStack.Count() < fMaxDepth )
- {
- CGenericLink* link = new CGenericLink(entry);
- fStack.AddFirst(link);
- return kODTrue;
- }
- else
- return kODFalse;
- }
-
- void* CStack::PopEntry()
- {
- if ( fStack.IsEmpty() )
- return kODNULL;
- else
- {
- CGenericLink* link = (CGenericLink*)fStack.RemoveFirst();
- return link->GetValue();
- }
- }
-
-
- //====================================================================
- // CQueue
- //====================================================================
-
- CQueue::CQueue()
- {
- fMaxEntries = USHRT_MAX;
- }
-
- CQueue::~CQueue()
- {
- fQueue.DeleteAllLinks();
- }
-
- ODBoolean CQueue::IsEmpty()
- {
- return fQueue.IsEmpty();
- }
-
- void CQueue::EmptyQueue(ODBoolean deleteEntries)
- {
- if ( deleteEntries )
- {
- LinkedListIterator iter(&fQueue);
- for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
- {
- delete (((CGenericLink*)link)->GetValue());
- fQueue.Remove(*link);
- }
- }
- else
- fQueue.DeleteAllLinks();
- }
-
- ODUShort CQueue::SetSize(ODUShort maxEntries)
- {
- ODULong curSize = fQueue.Count();
-
- if ( curSize > maxEntries )
- fMaxEntries = (ODUShort) curSize;
- else
- fMaxEntries = maxEntries;
-
- return fMaxEntries;
- }
-
- ODBoolean CQueue::AddEntry(void* entry)
- {
- if ( (ODUShort)fQueue.Count() < fMaxEntries )
- {
- CGenericLink* link = new CGenericLink(entry);
- fQueue.AddLast(link);
- return kODTrue;
- }
- else
- return kODFalse;
- }
-
- void* CQueue::GetEntry()
- {
- if ( fQueue.IsEmpty() )
- return kODNULL;
- else
- {
- CGenericLink* link = (CGenericLink*)fQueue.RemoveFirst();
- return link->GetValue();
- }
- }
-
-